package com.easycar.common.util;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;

import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;


/**
 * 签名文件夹下面内容解密
 */
public class ZipChannelUtil {
    // ZIP文件注释长度字段和MAGIC的字节数
    static final int SHORT_LENGTH = 2;
    //注释字符编码
    static final String UTF_8 = "UTF-8";
    // 文件最后用于定位的MAGIC字节
    static final byte[] MAGIC = new byte[]{0x21, 0x4b, 0x46, 0x5a, 0x53, 0x21}; //!KFZS!

    /**
     * 写入渠道号
     * @param file 执行该方法前应该首先确定该文件存在，否则可能会得到异想不到的结果
     * @param comment
     * @throws IOException
     */
    public static void writeQUA(File file, String comment) throws IOException {
        byte[] data = comment.getBytes(UTF_8);
        final RandomAccessFile raf = new RandomAccessFile(file, "rw");// rw 打开以便读取和写入。如果该文件尚不存在，则尝试创建该文件
        //定位到文件有效内容的末尾(文件长度-注释长度)
        raf.seek(file.length() - SHORT_LENGTH);
        //写入注释字节数{注释字节数+2(MAGIC长度说明)+MAGIC长度}
        writeShort(data.length + SHORT_LENGTH + MAGIC.length, raf);
        //写入注释内容
        writeBytes(data, raf);
        //写入MAGIC字节数
        writeShort(data.length, raf);
        //写入MAGIC
        writeBytes(MAGIC, raf);
        raf.close();
    }

    private static void writeBytes(byte[] data, DataOutput out) throws IOException {
        out.write(data);
    }

    private static void writeShort(int i, DataOutput out) throws IOException {
        ByteBuffer bb = ByteBuffer.allocate(SHORT_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
        bb.putShort((short) i);
        out.write(bb.array());
    }


    /**
     * 读取app 安装后存储的路径
     * @param context 上下文
     * @param packageName  包名
     * @return  路径
     */

    //读取源apk的路径
    public static String getSourceApkPath(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName))
            return null;
        try {
            ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
            return appInfo.sourceDir;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     *  读取渠道号
     * @param file   文件
     * @return  返回渠道信息
     * @throws IOException   IO  异常
     */
    public static String readQUA(File file) throws IOException {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "r");
            long index = raf.length();
            byte[] buffer = new byte[MAGIC.length];
            index -= MAGIC.length;
            //定位到MAGIC处
            raf.seek(index);
            //读取MAGIC
            raf.readFully(buffer);
            //判断文件末尾是否存在MAGIC字符
            if (isMagicMatched(buffer)) {
                index -= SHORT_LENGTH;
                raf.seek(index);
                //读取渠道号长度
                int length =  readShort(raf);
                if (length > 0) {
                    index -= length;
                    raf.seek(index);
                    //读取渠道号
                    byte[] bytesComment = new byte[length];
                    raf.readFully(bytesComment);
                    return new String(bytesComment, UTF_8);
                }
            }
        } finally {
            if (raf != null) {
                raf.close();
            }
        }
        return "";
    }
    //是否已经添加渠道号
    public static boolean isAddQUA(File file) throws IOException {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "r");
            long index = raf.length();
            byte[] buffer = new byte[MAGIC.length];
            index -= MAGIC.length;
            //定位到MAGIC处
            raf.seek(index);
            //读取MAGIC
            raf.readFully(buffer);
            //判断文件末尾是否存在MAGIC字符
            return isMagicMatched(buffer);
        } finally {
            if (raf != null) {
                raf.close();
            }
        }
    }
    private static final boolean GET_TWO = false;
    private static int readShort(RandomAccessFile raf) throws IOException {
        byte[] buffer = new byte[SHORT_LENGTH];
        raf.read(buffer);
        if(GET_TWO)
            return buffer[0] + buffer[1]*16*16;//0a00中 0a 10 ,00 0 -> 10+0*256 = 10
        else
            return buffer[0];
    }

    /**
     * 判断是否存在渠道号
     * @param buffer
     * @return
     */
    private static boolean isMagicMatched(byte[] buffer) {
        if (buffer.length != MAGIC.length) {
            return false;
        }
        for (int i = 0; i < MAGIC.length; ++i) {
            if (buffer[i] != MAGIC[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 删除渠道
     * @param file
     * @throws IOException
     */
    public static void delQUA(File file) throws IOException {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "rw");
            long index = raf.length();
            byte[] buffer = new byte[MAGIC.length];
            index -= MAGIC.length;
            //定位到MAGIC处
            raf.seek(index);
            //读取MAGIC
            raf.readFully(buffer);
            //判断文件末尾是否存在MAGIC字符
            if (isMagicMatched(buffer)) {
                index -= SHORT_LENGTH;
                raf.seek(index);
                //读取注释中渠道长度
                int length =  readShort(raf);
                if (length > 0) {
                    index -= length;
                    //跳过注释
                    raf.seek(index);
                    //跳过注释长度
                    index -= SHORT_LENGTH;
                    raf.seek(index);
                    byte[] NO_COMMENT = new byte[]{0x00, 0x00};
                    writeBytes(NO_COMMENT, raf);
                    long newLength = index + NO_COMMENT.length;
                    raf.setLength(newLength);
                }
            }
        } finally {
            if (raf != null) {
                raf.close();
            }
        }
    }
}
